package com.jinmdz.fmis.api.api.service;

import com.jinmdz.fmis.api.api.model.common.IdVersionData;
import com.jinmdz.fmis.api.api.model.funeral.FuneralSuppliesData;
import com.jinmdz.fmis.api.base.BaseService;
import com.jinmdz.fmis.api.constant.MessageConst;
import com.jinmdz.fmis.api.model.config.dictionary.BusinessLogCode;
import com.jinmdz.fmis.api.model.config.dictionary.OperationLogCode;
import com.jinmdz.fmis.api.model.system.UserItem;
import com.jinmdz.fmis.api.wrapper.ChargeWrapper;
import com.jinmdz.fmis.api.wrapper.OperationWrapper;
import com.jinmdz.fmis.common.ext.StringBuilderExt;
import com.jinmdz.fmis.common.util.DataUtil;
import com.jinmdz.fmis.core.base.BaseResult;
import com.jinmdz.fmis.core.constant.EBusinessType;
import com.jinmdz.fmis.core.exception.ActionException;
import com.jinmdz.fmis.core.util.JacksonUtil;
import com.jinmdz.fmis.dao.dao.ChargeItemDao;
import com.jinmdz.fmis.dao.dao.FuneralBusinessDao;
import com.jinmdz.fmis.dao.dao.ServiceItemDao;
import com.jinmdz.fmis.dao.model.charge.ChargeItem;
import com.jinmdz.fmis.dao.model.funeral.FuneralBusinessViewItem;
import com.jinmdz.fmis.mapper.entity.ChargeItemEntity;
import com.jinmdz.fmis.mapper.entity.FuneralBusinessLogEntity;
import com.jinmdz.fmis.mapper.mapper.ChargeItemMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;

/**
 * FuneralSuppliesService类
 *
 * @author LiCongLu
 * @date 2020-01-20 11:23
 */
@Service("funeralSuppliesService")
public class FuneralSuppliesService extends BaseService {

    @Resource
    private FuneralBusinessDao funeralBusinessDao;

    @Resource
    private ServiceItemDao serviceItemDao;

    @Resource
    private ChargeItemDao chargeItemDao;

    @Resource
    private ChargeWrapper chargeWrapper;

    @Resource
    private OperationLogCode operationLogCode;

    @Resource
    private BusinessLogCode businessLogCode;

    @Resource
    private ChargeItemMapper chargeItemMapper;

    @Resource
    private OperationWrapper operationWrapper;

    /**
     * 保存丧葬用品洽谈信息到费用表中
     *
     * @param userItem 当前帐号
     * @param data     丧葬用品
     * @return
     * @author LiCongLu
     * @date 2020-02-15 22:53
     */
    @Transactional(rollbackFor = Exception.class)
    public BaseResult<FuneralSuppliesData> saveFuneralSupplies(UserItem userItem, FuneralSuppliesData data) throws ActionException {
        String businessCode = data.getBusinessCode();
        // 通过业务编码获取殡葬信息
        FuneralBusinessViewItem funeralItem = funeralBusinessDao.getFuneralBusinessViewByBusinessCode(businessCode);
        if (DataUtil.isNull(funeralItem) || DataUtil.isNull(funeralItem.getId(), funeralItem.getVersion())) {
            throw exception(MessageConst.NO_FUNERAL_CODE);
        }

        String businessType = EBusinessType.TYPE_OF_FUNERAL_SUPPLIES.getType();
        // 更新物品服务
        ArrayList<ChargeItemEntity> chargeEntities = chargeWrapper.insertGoodsServices(userItem, data.getBusinessCode(), businessType, businessType, data.getGoodsServices());

        // 添加业务及操作日志
        Integer logTypeCode = operationLogCode.getChargeInsert();
        Integer chargeLogTypeCode = operationLogCode.getChargeInsert();
        saveFuneralSuppliesLog(userItem, funeralItem, data, logTypeCode, chargeLogTypeCode, chargeEntities);

        FuneralSuppliesData loadData = new FuneralSuppliesData();
        ArrayList<ChargeItem> goodsServices = chargeItemDao.listChargeItemByRandomCode(businessCode, businessType, 0);
        loadData.setBusinessCode(businessCode)
                .setGoodsServices(goodsServices);

        // 返回响应结果
        return successData(loadData);
    }

    /**
     * 添加丧葬用品日志记录
     *
     * @param userItem          当前帐号
     * @param funeralItem       当前业务
     * @param data              请求数据
     * @param logTypeCode       日志记录类型
     * @param chargeLogTypeCode 费用日志类型
     * @param chargeEntities    费用记录
     * @return
     * @author LiCongLu
     * @date 2020-03-06 16:15
     */
    private void saveFuneralSuppliesLog(UserItem userItem, FuneralBusinessViewItem funeralItem
            , FuneralSuppliesData data, Integer logTypeCode, Integer chargeLogTypeCode
            , ArrayList<ChargeItemEntity> chargeEntities) throws ActionException {

        // 添加业务日志及操作日志
        String businessCode = funeralItem.getBusinessCode();
        Integer typeCode = businessLogCode.getChargeInsert();
        FuneralBusinessLogEntity businessLogEntity = operationWrapper.businessLog(userItem, businessCode, typeCode);

        // 操作日志字符串
        StringBuilderExt builder = new StringBuilderExt();
        builder.format("添加丧葬用品信息，业务编码[{0}]，逝者姓名[{1}]，操作人员[{2}]"
                , businessCode, funeralItem.getDeadName()
                , userItem.getFullName());

        // 添加日志
        operationWrapper.operationLog(userItem, businessLogEntity, logTypeCode, builder);

        // 累计费用总金额
        if (DataUtil.valid(chargeEntities)) {
            BigDecimal sumCharge = new BigDecimal(0);
            for (ChargeItemEntity chargeEntity : chargeEntities) {
                sumCharge = sumCharge.add(chargeEntity.getItemCharge());
            }

            // 添加物品服务费用日志
            builder.clear();
            builder.format("添加丧葬用品信息费用，业务编码[{0}]，逝者姓名[{1}]，物品服务总金额[{2}]"
                    , businessCode, funeralItem.getDeadName(), DataUtil.getPlainString(sumCharge));
            operationWrapper.operationLog(userItem, businessLogEntity, chargeLogTypeCode
                    , builder.toString(), JacksonUtil.obj2Json(data.getGoodsServices()), null, JacksonUtil.obj2Json(chargeEntities));
        }
    }

    /**
     * 从费用表中删除指定id的丧葬用品任务信息记录
     *
     * @param userItem 当前帐号
     * @param data     主键和版本号
     * @return
     * @author LiCongLu
     * @date 2020-02-15 22:50
     */
    @Transactional(rollbackFor = Exception.class)
    public BaseResult deleteFuneralSuppliesWithId(UserItem userItem, IdVersionData data) throws ActionException {
        // 判断费用信息
        ChargeItem loadItem = chargeItemDao.getChargeItemById(data.getId());
        if (DataUtil.isNull(loadItem) || DataUtil.isNull(loadItem.getId(), loadItem.getVersion())) {
            return failure("主键错误，不存在此费用信息");
        }

        // 验证费用版本
        if (loadItem.getVersion().intValue() != data.getVersion().intValue()) {
            return failure(versionError("费用信息"));
        }

        // 判断是否结算
        if (DataUtil.valid(loadItem.getAsSettled())) {
            return failure("费用已经结算，无法进行删除");
        }

        // 判断是否退费
        if (DataUtil.valid(loadItem.getAsRefund())
                || DataUtil.valid(loadItem.getRefundId())) {
            return failure("费用为退费关联费用，无法进行删除");
        }

        // 验证是否业务费用
        if (DataUtil.valid(loadItem.getAsBusiness())) {
            return failure("此费用为业务费用，无法进行修改");
        }

        // 删除费用信息
        chargeItemMapper.deletedForChargeItem(loadItem.getId(), userItem.getId(), loadItem.getVersion());

        // 删除日志信息
        deleteFuneralSuppliesLog(userItem, loadItem);

        return success("删除完成");
    }

    /**
     * 删除丧葬用品
     *
     * @param userItem   当前账号
     * @param chargeItem 业务费用
     * @return
     * @author LiCongLu
     * @date 2020-02-25 16:25
     */
    private void deleteFuneralSuppliesLog(UserItem userItem, ChargeItem chargeItem) throws ActionException {
        // 添加业务日志及操作日志
        String businessCode = chargeItem.getBusinessCode();
        Integer typeCode = businessLogCode.getChargeDelete();
        FuneralBusinessLogEntity businessLogEntity = operationWrapper.businessLog(userItem, businessCode, typeCode);
        // 操作日志字符串
        StringBuilderExt builder = new StringBuilderExt();
        builder.format("删除丧葬用品信息，业务编码[{0}]，操作人员[{1}]", businessCode, userItem.getFullName());
        // 添加日志
        Integer logTypeCode = operationLogCode.getFaceLiftUpdate();
        operationWrapper.operationLog(userItem, businessLogEntity, logTypeCode, builder.toString(), null, JacksonUtil.obj2Json(chargeItem), null);

        // 累计费用总金额
        Integer chargeLogTypeCode = operationLogCode.getChargeDelete();
        // 添加删除费用日志
        builder.clear();
        builder.format("删除丧葬用品信息，业务编码[{0}]，整容费用[{1}]", businessCode
                , DataUtil.getPlainString(chargeItem.getItemCharge()));
        operationWrapper.operationLog(userItem, businessLogEntity, chargeLogTypeCode
                , builder.toString(), null, JacksonUtil.obj2Json(chargeItem), null);
    }
}
